/*
 License
 
 Copyright © 2012 Kevin Kimmich
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights to 
 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 the Software, and to permit persons to whom the Software is furnished to do so, 
 subject to the following conditions:
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/**
 @file
 This is an example file.
 
 This shows how to initialize and use an HTTP server object.
 */

#include "crcore.h"
#include "kuato_server.h"
#include "kuato_http_operations.h"

//This is the http server object, it's initialized in the http_server() function below.
http_server_object h;

/**
 This gets called by the web server after it parses a GET or POST request.
 */
void open_file(method* m)
{
	stream body;
	stream_init(&body,UNBOUNDED);
	stream_printf(&body,"<html><head></head><body><p>It Works!!!</p><p>Path = %s</p></body></html>",m->req.uri.path);
	do_http_response(m,"text/html",HTTP_OK,NULL,&body);
	stream_cleanup(&body);
}

void open_file2(method* m)
{
	stream body;
	stream_init(&body,UNBOUNDED);
	stream_printf(&body,"<html><head></head><body><p>It Works 2!!!</p><p>Path = %s</p></body></html>",m->req.uri.path);
	do_http_response(m,"text/html",HTTP_OK,NULL,&body);
	stream_cleanup(&body);
}

void post_it(method* m)
{
	stream body;
	stream_init(&body,UNBOUNDED);
	stream_printf(&body,"<html><head></head><body><p>Post It Works!!!</p><p>Path = %s</p></body></html>",m->req.uri.path);
	do_http_response(m,"text/html",HTTP_OK,NULL,&body);
	stream_cleanup(&body);
}

void uppercase(method* m)
{
	char* path = strdup(m->req.uri.path);
	char* p = &path[strlen("/uppercase/")];
	char * tmp = p;
	for(;p[0];p++)
		if(p[0] >= 'a' && p[0] <= 'z') p[0]= 'A' + (p[0]-'a');
	                
	p = tmp;

	stream body;
	stream_init(&body,UNBOUNDED);
	stream_printf(&body,"<html><head></head><body><p>Make %s Uppercase</p><p>Path = %s</p></body></html>",m->req.uri.path,p);
	do_http_response(m,"text/html",HTTP_OK,NULL,&body);
	stream_cleanup(&body);

	free(path);
}

void stream_file( method* m )
{
	FILE* f = fopen("test.mpeg","r");
	if(f==NULL)
	{
		http_server_write_chunk(m,0,NULL);
		return;
	}
	
	int err = 0;
	char buf[4096];
	for(;;)
	{
		int readed = fread(buf,1,4096,f);
		if(readed <= 0)
			break;
		
		if(http_server_write_chunk(m,readed,buf))
		{
			err = 1;
			break;
		}
	}
	
	printf("Error = %d\n",err);
	
	if(f)
		fclose(f);
	
	if(err==0)
		http_server_write_chunk(m,0,NULL);
}

/**
 This is the initialization function for the web server.
 */
void http_server(void)
{
	signal(SIGPIPE,SIG_IGN);
	
	if(http_server_init(&h))
		return;
	
	http_server_bind(&h,"0.0.0.0",9080,NULL,NULL);
	connection_context* ctx = http_server_bind(&h,"0.0.0.0",9081,NULL,NULL);
	
	//http_server_bind(&h,"0.0.0.0",9081,"certs/server.crt","certs/server.key");
		
	const char* domain_aliases[] = {".*",NULL};
	char root[LOCAL_BUF_SIZE];
	getcwd(root,LOCAL_BUF_SIZE);
	strcat(root,"/docs/html");
	
	//one or more domains are bound to the server object
	//in this case, the domain name is "www.crcycling.org", and it also has
	//an alias of ".*", that is, anything
	//if domain_aliases is {NULL}, then only requests to "www.crcycling.org" will be responded to
	domain_object* d = http_server_add_domain(&h,root,"index.html","localhost",domain_aliases);
	
	//void http_server_add_match_rule(domain* d, handler_t htype, void* priv, int count, ...);
	

	http_server_add_match_rule(d,discrete,http_reject,1,match_context,ctx);
	http_server_add_match_rule(d,discrete,uppercase,1,match_path,"^/uppercase/.*");
	//http_server_add_match_rule(d,discrete,open_file,1,match_address,"127.0.0.0/255.0.0.0");
	//http_server_add_match_rule(d,discrete,open_file2,1,match_path,"/stream/specific/*");
	//http_server_add_match_rule(d,discrete,http_reject,1,invert_match_path,"/stream/*");
	//http_server_add_match_rule(d,chunked,stream_file,1,match_path,"/stream/*");
	//http_server_add_match_rule(d,discrete,http_reject,1,match_any,NULL);
}


int main(int argc, char** argv)
{
	printf("Starting the web server to listen on port 9080!\n");
	
	//fork, setsid, exit parent, and close all stdXXX outputs.
	//daemon_init();
	
	//This call initializes the www library.
	www_init();
	
	//this call intializes the http server.
	http_server();
	
	//don't exit.
	for(;;)
	{
		sleep(1);
	}
	
	return 0;
}
